package com.huawei.java.main;

import com.huawei.java.main.inputentity.Require;
import com.huawei.java.main.inputentity.ServerType;
import com.huawei.java.main.inputentity.VmType;

import java.io.*;
import java.util.*;

public class Input {
    public static Map<String, ServerType> serverMap = new HashMap<>();//服务器型号列表
    public static Map<String, VmType> visualMachineMap = new HashMap<>();//虚拟机型号列表

    //每天请求，列表中每一个元素为一天的请求，每天的请求被分为删除请求和添加请求，分别通过map.get("del")和map.get("add")来获取
    public static List<Map<String,List<Require>>> dailyRequireList = new LinkedList<>();

    /**
     * 处理输入数据
     * @param arr
     */
    public static void resolve(String[] arr){

        //1.获取服务器类型
        int serverNumber=Integer.parseInt(arr[0]);
        String[] servers = Arrays.copyOfRange(arr,1,serverNumber+1);
//            System.out.println("服务器："+servers.length);
        serverMap = getSortedServers(servers);

        //2.获取虚拟机类型
        int visualNumber=Integer.parseInt(arr[serverNumber+1]);
        String[] visuals = Arrays.copyOfRange(arr,serverNumber+2,visualNumber+serverNumber+2);
//            System.out.println("虚拟机："+visuals.length);
        visualMachineMap = getVisualMachine(visuals);

        //3.获取每天的请求
        int start=serverNumber+visualNumber+2;
        int days=Integer.parseInt(arr[start]);
//            System.out.println("总天数："+days);
        for(int i=0;i<days;i++){
            start++;
            int commands=Integer.parseInt(arr[start]);//指令行数
            int end=start+commands;
//                System.out.println(commands);
            String[] comm = Arrays.copyOfRange(arr,start+1,end+1);
//                System.out.println(Arrays.toString(comm));
            dailyRequireList.add(getRequire(comm));

            start=end;
        }

    }

    /**
     * 读取文件
     * @param filePath
     * @return
     * @throws IOException
     */
    public static String[] readFile(String filePath) {
        String message = "";
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(filePath)))){
            int len = 0;
            byte[] buffer = new byte[10000000];//要设大一点，数据比较大
            //获取所有字符
            while ((len = bis.read(buffer)) != -1){
                message = new String(buffer,0,len); //为防止中文乱码，设置字符集为GBK
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return message.split("\n|\r\n"); //将获取的字符按行分割

    }

    /**
     * 读取标准输入
     * @return
     * @throws IOException
     */
    public static void readStdIn() {
        Scanner in = new Scanner(System.in);
        //1.服务器
        int serverNum = in.nextInt();
        in.nextLine();
        List<String> temp = new ArrayList<>(100);
        for (int i=0;i<serverNum;i++){
            String mes = in.nextLine();
            temp.add(mes);
        }
        serverMap = getSortedServers(temp.toArray(new String[0]));
        //2.虚拟机
        int vmNum=in.nextInt();
        in.nextLine();
        temp.clear();
        for(int i=0;i<vmNum;i++){
            String mes = in.nextLine();
            temp.add(mes);
        }
        visualMachineMap = getVisualMachine(temp.toArray(new String[0]));
        //3.每天请求
        int days=in.nextInt();
        in.nextLine();
        for (int i=0;i<days;i++){
            int requireNum = in.nextInt();
            in.nextLine();
            temp.clear();
            for(int j=0;j<requireNum;j++){
                String req = in.nextLine();
                temp.add(req);
            }
            dailyRequireList.add(getRequire(temp.toArray(new String[0])));
        }

    }


    /**
     * 解析每日虚拟机请求
     * @param comms
     * @return
     */
    private static Map<String,List<Require>> getRequire(String[] comms) {
        Map<String,List<Require>> map = new HashMap<>();
        List<Require> addList = new LinkedList<>();
        List<Require> delList = new LinkedList<>();
        for(String str:comms){
            String[] arr= str.substring(1, str.length() - 1).split(", ");
            Require require = new Require();
            require.setRequireType(arr[0]);
            if (arr[0].equals("add")){//加入到addList中
                require.setVmName(arr[1]);
                require.setVmType(Input.visualMachineMap.get(arr[1]));//设置需要的虚拟机
                require.setVmId(Integer.parseInt(arr[2]));
                addList.add(require);
            }else if(arr[0].equals("del")) {//加入到delList中
                require.setVmId(Integer.parseInt(arr[1]));
                delList.add(require);
            }
            //对addList中的请求按照核内比进行升序排序
//            addList.sort((o1, o2) -> {
//                double val1=o1.getVm().getCpuAndMemRatio();
//                double val2=o2.getVm().getCpuAndMemRatio();
//                if (val1==val2) return 0;
//                return val1-val2>0?1:-1;
//            });

            map.put("addList",addList);
            map.put("delList",delList);
        }
        return map;
    }

    /**
     * 解析所有虚拟机型号
     * @param visuals
     * @return
     */
    private static Map<String, VmType> getVisualMachine(String[] visuals) {
        Map<String, VmType> map=new HashMap<>();
        for(String str:visuals){
            String[] arr= str.substring(1, str.length() - 1).split(", ");
            VmType vm = new VmType(arr[0],Integer.parseInt(arr[1]),Integer.parseInt(arr[2]),Integer.parseInt(arr[3]));
//            System.out.println(vm);
            map.put(vm.getVMType(),vm);
        }
        return map;
    }

    /**
     * 解析所有服务器型号，并按照性价比对服务器进行升序排序
     * 性价比数值越低，性价比越高
     * @param servers
     * @return
     */
    static Map<String, ServerType> getSortedServers(String[] servers){
        Map<String, ServerType> map = new HashMap<>();
        for(String str:servers){
            String[] arr= str.substring(1, str.length() - 1).split(", ");
            ServerType serverType = new ServerType(arr[0],Integer.parseInt(arr[1]),Integer.parseInt(arr[2]),
                    Integer.parseInt(arr[3]),
                    Integer.parseInt(arr[4]));
            map.put(serverType.getServerType(),serverType);
//            System.out.println(server);
        }
        //按性价比进行降序排序
        List<Map.Entry<String, ServerType>> list = new ArrayList<>(map.entrySet());
        list.sort(Comparator.comparingInt(o -> o.getValue().getCostPerformance()));
        Map<String, ServerType> sortedMap = new LinkedHashMap<>();//注意得用LinkedHashMap来存，不然无法保存排序
        for(Map.Entry<String, ServerType> servers1:list){
            sortedMap.put(servers1.getKey(),servers1.getValue());
        }


        return sortedMap;
    }
}
